/*!
 * \file WTSHotMgr.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 主力合约管理实现
 * \details 实现主力合约和次主力合约的管理功能，包括合约切换、时段分割等核心功能
 */
#pragma once
#include "../Includes/IHotMgr.h"
#include "../Includes/FasterDefs.h"
#include "../Includes/WTSCollection.hpp"
#include <string>

NS_WTP_BEGIN
	class IMarketMgr;
	class WTSHotItem;
NS_WTP_END

USING_NS_WTP;

/*!
 * \brief 日期到主力合约的映射
 * \details 用于存储每个日期对应的主力合约信息
 */
typedef WTSMap<uint32_t>		WTSDateHotMap;

/*!
 * \brief 品种到主力合约的映射
 * \details 用于存储每个品种对应的主力合约信息
 */
typedef WTSMap<std::string>		WTSProductHotMap;

/*!
 * \brief 交易所到主力合约的映射
 * \details 用于存储每个交易所对应的主力合约信息
 */
typedef WTSMap<std::string>		WTSExchgHotMap;

/*!
 * \brief 主力合约管理器
 * \details 实现主力合约和次主力合约的管理功能，包括：
 * 1. 主力合约和次主力合约的加载和解析
 * 2. 合约代码的转换和查询
 * 3. 合约切换时段的划分
 * 4. 主力合约和次主力合约的状态判断
 */
class WTSHotMgr : public IHotMgr
{
public:
	/*!
	 * \brief 构造函数
	 * \details 初始化主力合约管理器的各个映射容器
	 */
	WTSHotMgr();

	/*!
	 * \brief 析构函数
	 * \details 释放所有映射容器的内存
	 */
	~WTSHotMgr();

public:
	/*!
	 * \brief 加载主力合约配置
	 * \param filename 配置文件路径
	 * \return 加载成功返回true，失败返回false
	 * \details 解析配置文件，加载所有主力合约信息到内存
	 */
	bool loadHots(const char* filename);

	/*!
	 * \brief 加载次主力合约配置
	 * \param filename 配置文件路径
	 * \return 加载成功返回true，失败返回false
	 * \details 解析配置文件，加载所有次主力合约信息到内存
	 */
	bool loadSeconds(const char* filename);

	/*!
	 * \brief 释放资源
	 * \details 释放所有映射容器的内存，通常在对象销毁前调用
	 */
	void release();

	/*!
	 * \brief 获取指定交易所的主力合约代码映射
	 * \param exchg 交易所代码
	 * \param mapHots 输出参数，存储主力合约代码映射
	 * \details 将指定交易所的所有主力合约代码映射到输出参数中
	 */
	void getHotCodes(const char* exchg, std::map<std::string, std::string> &mapHots);

	/*!
	 * \brief 检查是否有主力合约数据
	 * \return 有主力合约数据返回true，否则返回false
	 */
	bool hasHotCodes();

	/*!
	 * \brief 检查是否已初始化
	 * \return 已初始化返回true，否则返回false
	 */
	inline bool isInitialized() const {return m_bInitialized;}

public:
	/*!
	 * \brief 获取指定日期的主力合约代码
	 * \param exchg 交易所代码
	 * \param pid 品种ID
	 * \param dt 日期，格式为YYYYMMDD，默认为0表示当前日期
	 * \return 返回主力合约代码，如果不存在则返回NULL
	 */
	virtual const char* getRawCode(const char* exchg, const char* pid, uint32_t dt = 0) override;

	/*!
	 * \brief 获取指定日期的上一个主力合约代码
	 * \param exchg 交易所代码
	 * \param pid 品种ID
	 * \param dt 日期，格式为YYYYMMDD，默认为0表示当前日期
	 * \return 返回上一个主力合约代码，如果不存在则返回NULL
	 */
	virtual const char* getPrevRawCode(const char* exchg, const char* pid, uint32_t dt = 0) override;

	/*!
	 * \brief 获取指定日期的主力合约代码
	 * \param exchg 交易所代码
	 * \param rawCode 原始合约代码
	 * \param dt 日期，格式为YYYYMMDD，默认为0表示当前日期
	 * \return 返回主力合约代码，如果不存在则返回NULL
	 */
	virtual const char* getHotCode(const char* exchg, const char* rawCode, uint32_t dt = 0) override;

	/*!
	 * \brief 判断指定合约在指定日期是否为主力合约
	 * \param exchg 交易所代码
	 * \param rawCode 原始合约代码
	 * \param dt 日期，格式为YYYYMMDD，默认为0表示当前日期
	 * \return 是主力合约返回true，否则返回false
	 */
	virtual bool	isHot(const char* exchg, const char* rawCode, uint32_t dt = 0) override;

	/*!
	 * \brief 分割主力合约的时段
	 * \param exchg 交易所代码
	 * \param pid 品种ID
	 * \param sDt 开始日期，格式为YYYYMMDD
	 * \param eDt 结束日期，格式为YYYYMMDD
	 * \param sections 输出参数，存储分割后的时段信息
	 * \return 分割成功返回true，失败返回false
	 * \details 将指定日期范围内的主力合约切换时段分割成多个区间
	 */
	virtual bool	splitHotSecions(const char* exchg, const char* pid, uint32_t sDt, uint32_t eDt, HotSections& sections) override;

	//////////////////////////////////////////////////////////////////////////
	//次主力合约接口
	/*!
	 * \brief 获取指定日期的次主力合约代码
	 * \param exchg 交易所代码
	 * \param pid 品种ID
	 * \param dt 日期，格式为YYYYMMDD，默认为0表示当前日期
	 * \return 返回次主力合约代码，如果不存在则返回NULL
	 */
	virtual const char* getSecondRawCode(const char* exchg, const char* pid, uint32_t dt = 0) override;

	/*!
	 * \brief 获取指定日期的上一个次主力合约代码
	 * \param exchg 交易所代码
	 * \param pid 品种ID
	 * \param dt 日期，格式为YYYYMMDD，默认为0表示当前日期
	 * \return 返回上一个次主力合约代码，如果不存在则返回NULL
	 */
	virtual const char* getPrevSecondRawCode(const char* exchg, const char* pid, uint32_t dt = 0) override;

	/*!
	 * \brief 获取指定日期的次主力合约代码
	 * \param exchg 交易所代码
	 * \param rawCode 原始合约代码
	 * \param dt 日期，格式为YYYYMMDD，默认为0表示当前日期
	 * \return 返回次主力合约代码，如果不存在则返回NULL
	 */
	virtual const char* getSecondCode(const char* exchg, const char* rawCode, uint32_t dt = 0) override;

	/*!
	 * \brief 判断指定合约在指定日期是否为次主力合约
	 * \param exchg 交易所代码
	 * \param rawCode 原始合约代码
	 * \param d 日期，格式为YYYYMMDD，默认为0表示当前日期
	 * \return 是次主力合约返回true，否则返回false
	 */
	virtual bool		isSecond(const char* exchg, const char* rawCode, uint32_t d = 0) override;

	/*!
	 * \brief 分割次主力合约的时段
	 * \param exchg 交易所代码
	 * \param hotCode 主力合约代码
	 * \param sDt 开始日期，格式为YYYYMMDD
	 * \param eDt 结束日期，格式为YYYYMMDD
	 * \param sections 输出参数，存储分割后的时段信息
	 * \return 分割成功返回true，失败返回false
	 * \details 将指定日期范围内的次主力合约切换时段分割成多个区间
	 */
	virtual bool		splitSecondSecions(const char* exchg, const char* hotCode, uint32_t sDt, uint32_t eDt, HotSections& sections) override;

private:
	WTSExchgHotMap*	m_pExchgHotMap;		///< 交易所主力合约映射
	WTSExchgHotMap*	m_pExchgScndMap;		///< 交易所次主力合约映射
	faster_hashmap<ShortKey, std::string>	m_curHotCodes;	///< 当前主力合约代码映射
	faster_hashmap<ShortKey, std::string>	m_curSecCodes;	///< 当前次主力合约代码映射
	bool			m_bInitialized;			///< 是否已初始化标志
};

